package cn.dgut.training.service.impl;


import cn.dgut.training.controller.ActivityService;
import cn.dgut.training.controller.GoodsService;
import cn.dgut.training.controller.UserService;
import cn.dgut.training.dto.transaction.OrdersSubDTO;
import cn.dgut.training.e.Status;
import cn.dgut.training.emun.OrderStatusEnum;
import cn.dgut.training.entity.activity.Coupon;
import cn.dgut.training.entity.activity.CouponUser;
import cn.dgut.training.entity.activity.GroupBuying;
import cn.dgut.training.entity.goods.Cart;
import cn.dgut.training.entity.goods.GoodsProduct;
import cn.dgut.training.entity.transaction.GroupJoin;
import cn.dgut.training.entity.transaction.Orders;
import cn.dgut.training.entity.transaction.OrderGoods;
import cn.dgut.training.entity.transaction.OrderStatusTime;
import cn.dgut.training.entity.dto.OrdersDTO;
import cn.dgut.training.entity.dto.OrderGoodsDTO;
import cn.dgut.training.entity.user.Address;
import cn.dgut.training.entity.user.User;
import cn.dgut.training.entity.vo.OrderGoodsVO;
import cn.dgut.training.entity.vo.OrdersVO;
import cn.dgut.training.mapper.OrderGoodsMapper;
import cn.dgut.training.mapper.OrderMapper;
import cn.dgut.training.mapper.OrderStatusTimeMapper;
import cn.dgut.training.service.IOrderService;
import cn.dgut.training.utils.CodecUtil;
import cn.dgut.training.vo.CommonResponse;
import cn.dgut.training.vo.transaction.OrdersSubVO;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements IOrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private OrderGoodsMapper orderGoodsMapper;

    @Resource
    private OrderStatusTimeMapper orderStatusTimeMapper;

    @Resource
    private GoodsService goodsService;

    @Resource
    private ActivityService activityService;

    @Resource
    private UserService userService;

    @Resource
    private GroupJoinServiceImpl groupJoinService;


    /**
     * 根据条件分页查询订单列表
     *
     * @param ordersDTO
     * @return
     */
    @Override
    @Transactional
    public IPage<OrdersVO> listOrderLimit(OrdersDTO ordersDTO) {
        //得到条件构造器
        QueryWrapper<Orders> queryWrapper = OrdersDTO.getWrapper(ordersDTO);

        //分页查询得到订单列表
        IPage<Orders> iPage = new Page<>();
        BeanUtils.copyProperties(ordersDTO, iPage);
        IPage<Orders> orderIPage = orderMapper.selectPage(iPage, queryWrapper);
        List<Orders> ordersList = orderIPage.getRecords();
        IPage<OrdersVO> orderVOIPage = new Page<>();
        BeanUtils.copyProperties(orderIPage, orderVOIPage);
        if (ordersList != null) {
            List<OrdersVO> ordersVOList = ordersList.stream()
                    .map(order -> {
                        OrdersVO ordersVO = new OrdersVO();
                        BeanUtils.copyProperties(order, ordersVO);
                        return ordersVO;
                    }).collect(Collectors.toList());
            //新添
            for(OrdersVO ordersVO:ordersVOList)
            {
                List<OrderGoods> orderGoodsList = orderGoodsMapper.selectList(new QueryWrapper<OrderGoods>()
                        .lambda().eq(OrderGoods::getOrderId,ordersVO.getId()));
                List<OrderGoodsVO> orderGoodsVOList = new ArrayList<>();
                for (OrderGoods goods:orderGoodsList){
                    OrderGoodsVO orderGoodsVO= new OrderGoodsVO();
                    BeanUtils.copyProperties(goods,orderGoodsVO);
                    orderGoodsVOList.add(orderGoodsVO);
                }
                if(orderGoodsVOList.size()>0){
                    Set<OrderGoodsVO> orderGoods= new HashSet<>();
                    orderGoods.addAll(orderGoodsVOList);
                    ordersVO.setOrderGoodsVOS(orderGoods);
                }
            }
            orderVOIPage.setRecords(ordersVOList);
        }
        return orderVOIPage;
    }


    /**
     * 通过订单的id查询订单详情
     *
     * @param id
     * @return
     */
    @Override
    public OrdersVO selectOrderById(Long id) {
        Orders orders = orderMapper.selectById(id);
        Set<OrderGoodsVO> orderGoodsVOSet = new HashSet<>();
        Set<OrderGoods> orderGoodsSet = new HashSet<>(orderGoodsMapper.selectList(new QueryWrapper<OrderGoods>().eq("order_id", id)));
        orders.setOrderGoodsSet(orderGoodsSet);
        OrdersVO ordersVO = new OrdersVO();
        BeanUtils.copyProperties(orders, ordersVO);
        for (OrderGoods orderGoods : orderGoodsSet) {
            OrderGoodsVO orderGoodsVO = new OrderGoodsVO();
            BeanUtils.copyProperties(orderGoods, orderGoodsVO);
            orderGoodsVOSet.add(orderGoodsVO);
        }
        ordersVO.setOrderGoodsVOS(orderGoodsVOSet);
        return ordersVO;
    }

    /**
     * 更改订单状态
     *
     * @param ordersDTO
     * @return
     */
    @Override
    @Transactional
    public OrdersVO updateOrderStatus(OrdersDTO ordersDTO) {

        //更改订单状态
        Orders orders = orderMapper.selectById(ordersDTO.getId());
        BeanUtils.copyProperties(ordersDTO, orders);
        orderMapper.updateById(orders);

        //更新订单状态-时间表
        OrderStatusTime orderStatusTime = new OrderStatusTime();
        orderStatusTime.setOrderSn(ordersDTO.getOrderSn());
        orderStatusTime.setOrderId(orders.getId());
        orderStatusTime.setOrderStatus(ordersDTO.getOrderStatus());
        orderStatusTimeMapper.insert(orderStatusTime);

        //如果是用户取消订单，把商品库存加回去
        if (ordersDTO.getOrderStatus().equals(OrderStatusEnum.CANCELLATION_OF_USER.getValue())) {
            List<OrderGoods> orderGoodsList = orderGoodsMapper.selectList(new QueryWrapper<OrderGoods>()
                    .lambda()
                    .eq(OrderGoods::getOrderId, ordersDTO.getId()));
            for (OrderGoods goods : orderGoodsList) {
                goodsService.updateStock(goods.getProductId(), goods.getNumber());
            }
        }

        OrdersVO ordersVO = new OrdersVO();
        BeanUtils.copyProperties(orders, ordersVO);
        return ordersVO;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public CommonResponse submitOrders(OrdersSubDTO ordersSubDTO) {

        if (ordersSubDTO.getCartId() == null || ordersSubDTO.getAddressId() == null || ordersSubDTO.getCouponId() == null) {
            return CommonResponse.fail(Status.ORDERS_SUBMIT_ERROR.getCode(), Status.ORDERS_SUBMIT_ERROR.getMessage());
        }

        //收货地址 gia
        Address address = userService.iGetById(ordersSubDTO.getAddressId());

        //团购优惠 gia
        //如果是团购项目,验证活动是否有效
        BigDecimal groupBuyingPrice=new BigDecimal(0.00);
        if (ordersSubDTO.getGrouponLinkId() != null&&ordersSubDTO.getGrouponLinkId()!=0L) {
            GroupBuying groupBuying = activityService.iGetById(ordersSubDTO.getGrouponLinkId());
            if (groupBuying.getStatus()!=0){
                return CommonResponse.fail(Status.ORDERS_SUBMIT_ERROR.getCode(),Status.ORDERS_SUBMIT_ERROR.getMessage()+"团购异常");
            }
            else{
                groupBuyingPrice=groupBuying.getDiscount();
            }
        }


        //用户信息 gia
        User user = userService.iGetUserById(ordersSubDTO.getUserId());

        //列出购物车
        List<Cart> cartList = new ArrayList<>();
        if (ordersSubDTO.getCartId().equals(0L)) {
            cartList = goodsService.listChecked(ordersSubDTO.getUserId());
        } else {
            Cart cart = goodsService.findById(ordersSubDTO.getCartId());
            if (cart == null) {
                return CommonResponse.fail(Status.ORDERS_SUBMIT_ERROR.getCode(), Status.ORDERS_SUBMIT_ERROR.getMessage() + ":购物车商品不存在");
            }
            cartList.add(cart);
        }
        if (cartList.size() == 0) {
            return CommonResponse.fail(Status.ORDERS_SUBMIT_ERROR.getCode(), Status.ORDERS_SUBMIT_ERROR.getMessage() + ":购物车不存在");
        }

        //计算货品价格
        BigDecimal checkedGoodsPrice = new BigDecimal(0.00);
        for (Cart cart : cartList) {
                checkedGoodsPrice = checkedGoodsPrice.add(cart.getPrice().multiply(new BigDecimal(cart.getProductNumber())));
        }

        //获得优惠券信息
        BigDecimal couponPrice = new BigDecimal(0.00);
        // 如果couponId=0则没有优惠券，couponId=-1则不使用优惠券
        if (ordersSubDTO.getCouponId() != 0L && ordersSubDTO.getCouponId() != -1L) {
            Coupon coupon = activityService.orderUse(ordersSubDTO.getUserId(), ordersSubDTO.getCouponId());
            if (coupon == null) {
                return CommonResponse.fail(Status.ORDERS_SUBMIT_ERROR.getCode(), Status.ORDERS_SUBMIT_ERROR.getMessage() + ":优惠券不存在");
            }
            couponPrice = coupon.getAmount();
        }

        //计算运费
        BigDecimal freightPrice = new BigDecimal(0.00);
        if (checkedGoodsPrice.compareTo(new BigDecimal(88.00)) < 0) {
            freightPrice = new BigDecimal(8.00);
        }

        //用户积分 gia
        BigDecimal integralPrice = new BigDecimal(0.00);
        // 订单费用
        BigDecimal orderTotalPrice = checkedGoodsPrice.add(freightPrice).subtract(couponPrice).subtract(groupBuyingPrice).max(new BigDecimal(0));
        // 最终支付费用
        BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice);

        Orders orders = new Orders();

        // 订单入库 gia
        orders.setActualPrice(actualPrice).setOrderPrice(orderTotalPrice)
                .setUserAddress(address.getAddressDetail()).setUserId(ordersSubDTO.getUserId())
                .setUserMessage(ordersSubDTO.getMessage()).setMobile(address.getTel())
                .setConsignee(address.getName()).setCouponPrice(couponPrice)
                .setFreightPrice(freightPrice).setTeamPrice(null)
                .setGoodsPrice(checkedGoodsPrice).setIntegralPrice(integralPrice)
                .setNevaluatedNum(null).setOrderSn(CodecUtil.createSn("o"))
                .setOrderStatus(OrderStatusEnum.WAITING_FOR_PAYMENT.getValue());

        //如果是团购商品则将订单状态设置为团购已付款
        if (ordersSubDTO.getGrouponLinkId() != null&&ordersSubDTO.getGrouponLinkId()!=0L) {
            GroupBuying groupBuying = activityService.iGetById(ordersSubDTO.getGrouponLinkId());
            if (groupBuying.getStatus()!=1){
                orders.setOrderStatus(OrderStatusEnum.PAY_FOR_GROUPBUY.getValue());
            }
        }
        orderMapper.insert(orders);

        //订单商品表入库
        for (Cart cart : cartList) {
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setGoodsId(cart.getGoodsId());
            orderGoods.setGoodsName(cart.getGoodsName());
            orderGoods.setNumber(cart.getProductNumber());
            orderGoods.setProductId(cart.getProductId());
            orderGoods.setPrice(cart.getPrice());
            orderGoods.setPicUrl(cart.getPicUrl());
            orderGoods.setSpecifications(cart.getSpecifications());
            orderGoods.setOrderId(orders.getId());
            orderGoods.setGoodsSn(cart.getGoodsSn());
            orderGoodsMapper.insert(orderGoods);
            //商品库存减少 gia
            goodsService.updateStock(cart.getProductId(), ((-1) * cart.getProductNumber()));
        }

        //删除购物车里的商品
        goodsService.deleteChecked(ordersSubDTO.getUserId());


        // 如果使用了优惠券，设置优惠券使用状态 gia
        if (ordersSubDTO.getCouponId() != 0L && ordersSubDTO.getCouponId() != -1L) {

            activityService.useUserCoupon(ordersSubDTO.getCouponId(),orders.getId());
        }

        //如果是团购项目，添加团购信息 giao
        if (ordersSubDTO.getGrouponLinkId() != null&&ordersSubDTO.getGrouponLinkId()!=0L) {
            GroupBuying groupBuying = activityService.iGetById(ordersSubDTO.getGrouponLinkId());
            if (groupBuying.getStatus()!=0){
                return CommonResponse.fail(Status.ORDERS_SUBMIT_ERROR.getCode(),Status.ORDERS_SUBMIT_ERROR.getMessage()+"团购异常");
            }
            else{
                //更新团购活动
                Integer item=activityService.iUpdateActivity(ordersSubDTO.getGrouponLinkId());
                if (item==0){
                   GroupJoin groupJoin=new GroupJoin();
                   groupJoin.setOrderId(orders.getId());
                   groupJoin.setUserId(ordersSubDTO.getUserId());
                   groupJoin.setActivityId(ordersSubDTO.getGrouponLinkId());
                   groupJoinService.save(groupJoin);
                }
                else if(item==1){
                    //满足条件，订单设置为待发货
                    //找出满足这一团购规则的全部订单 giao
                    GroupJoin groupJoin=new GroupJoin();
                    groupJoin.setOrderId(orders.getId());
                    groupJoin.setUserId(ordersSubDTO.getUserId());
                    groupJoin.setActivityId(ordersSubDTO.getGrouponLinkId());
                    groupJoinService.save(groupJoin);
                    List<GroupJoin> groupJoinList=groupJoinService.list(new LambdaQueryWrapper<GroupJoin>()
                            .eq(GroupJoin::getActivityId,ordersSubDTO.getGrouponLinkId()));
                    for(GroupJoin groupJoin1:groupJoinList){
                        Orders orders1=orderMapper.selectById(groupJoin1.getOrderId());
                        orders1.setOrderStatus(OrderStatusEnum.WAITING_FOR_DELIVERY.getValue());
                        orderMapper.updateById(orders1);
                    }
                }
            }
        }

        OrdersSubVO ordersSubVO = new OrdersSubVO();
        ordersSubVO.setOrderId(orders.getId());
        ordersSubVO.setGrouponLinkId(ordersSubDTO.getGrouponLinkId()); //gia
        return CommonResponse.success(ordersSubVO);
    }

    @Override
    public CommonResponse updateGroupOrderStatus(@RequestParam("orderId") Long orderId){
        Orders orders = orderMapper.selectById(orderId);
        orders.setOrderStatus(-4);
        orderMapper.updateById(orders);

        return CommonResponse.success(orders);
    }


//    /**
//     * 创建编号的算法
//     * @return
//     */
//    private String getNumber(){
//        return DateTime.now().toString().replaceAll(" ","")
//                .replaceAll(":","")
//                .replaceAll("-","")+ UUID.randomUUID().toString().replaceAll("-", "");
//    }
}
